home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / Imaging Engine / RasterizeText.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  8.7 KB  |  318 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        RasterizeText.c
  3.  
  4.      Contains:    QuickDraw GX to PostScript conversion code.
  5.                          File contains code necessary to convert text
  6.                         into bitmaps.
  7.                     
  8.                         File contains Routines for the Imaging Engine Shape Parts Drones.
  9.  
  10.      Version:    Technology:    Quickdraw GX 1.1.x
  11.       
  12.      Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  13. */
  14.  
  15. #include "GXToPSBuildConfig.h"
  16. #include <GXGraphics.h>
  17. #include "GXGraphicsPriv.h"
  18. #include <GXEnvironment.h>
  19. #include "GXToPostScript.h"
  20. #include "PublicPostScriptIE.h"
  21. #include "private.h"
  22. #include "PSIEResources.h"
  23. #include "GXErrors.h"
  24.  
  25. #include "IOUtilities.h"
  26. #include "RDUtil.h"
  27.  
  28.  
  29. #ifndef SKIADOESNTDROPOUT
  30.  
  31. #define kMinPenWidth 0x00018000 /* 1.5 units */
  32.  
  33. /******************************************
  34.  
  35.     Function:        FixUpTextFace
  36.     
  37.     Routine goes through the text face of a style
  38.     and makes sure that all text faces will render
  39.     properly into bitmaps.
  40.     
  41.     1.        Any thin frames are converted to hairlines.
  42.     
  43. ********************************************/
  44. OSErr        FixUpTextFace(TIEGlobalsHdl hIEGlobals, gxStyle aStyle, gxMapping *finalMapping);
  45. OSErr        FixUpTextFace(TIEGlobalsHdl hIEGlobals, gxStyle aStyle, gxMapping *finalMapping)
  46.     {
  47.         OSErr                status;
  48.         long                nLayers, idx;
  49.         gxTextFace    *theFace;
  50.         gxFaceLayer    *theLayer;
  51.         Boolean            changedFace;
  52.         gxPoint            penPoint;
  53.         
  54.         if (aStyle == nil)
  55.             return(noErr);
  56.         
  57.         nLayers = GXGetStyleFace(aStyle, nil);
  58.         if (nLayers == 0)
  59.             return(noErr);
  60.             
  61.         status = PSSetWorkSpaceSize(hIEGlobals, sizeof(gxTextFace) + nLayers * sizeof(gxFaceLayer));
  62.         nrequire(status, failed_faceSpace);
  63.         
  64.         HLock((*hIEGlobals)->hWorkSpace);
  65.         theFace = (gxTextFace*)(*(*hIEGlobals)->hWorkSpace);        // Hope gx graphics calls don't move memory.
  66.         GXGetStyleFace(aStyle, theFace);
  67.         
  68.         /** Check each layer for thin hairlines and fix them if necessary **/        
  69.         
  70.         changedFace = false;
  71.         
  72.         theLayer = theFace->faceLayer;
  73.         
  74.         for (idx = 0; idx < nLayers; ++idx, ++theLayer) {
  75.         
  76.             if ((theLayer->outlineFill == gxClosedFrameFill) || (theLayer->outlineFill == gxOpenFrameFill) ) {
  77.  
  78.                 /** Get the pen width of the framed layer **/
  79.                 
  80.                 if (theLayer->outlineStyle != nil)
  81.                     penPoint.x = penPoint.y = GXGetStylePen(theLayer->outlineStyle);
  82.                 else
  83.                     penPoint.x = penPoint.y = ff(1);
  84.                 
  85.                 /** Run the pen width through the final mapping and see if it is too small **/
  86.                 
  87.                 MapPoints(finalMapping, 1, &penPoint);
  88.                 if (penPoint.x < 0) penPoint.x = -penPoint.x;            
  89.                 if (penPoint.y < 0) penPoint.y = -penPoint.y;
  90.  
  91.                 /** If it is too small, make it hairline **/
  92.                 
  93.                 if ( (penPoint.x < kMinPenWidth) || (penPoint.y < kMinPenWidth) ) {
  94.                     
  95.                     if (theLayer->outlineStyle == nil)
  96.                         theLayer->outlineStyle = GXNewStyle();            // we need a style to put a hairline on.
  97.                     
  98.                     GXSetStylePen(theLayer->outlineStyle, ff(0));
  99.                     changedFace = true;
  100.                     
  101.                 }//end if
  102.                 
  103.             }//end if
  104.         
  105.         }//end for
  106.         
  107.         /** If any changes were made, put the changed text face back in the style **/
  108.         
  109.         if (changedFace)
  110.             GXSetStyleFace(aStyle, theFace);
  111.         
  112.         /** Now dispose of any objects that were created by GXGetStyleFace **/
  113.         theLayer = theFace->faceLayer;
  114.         
  115.         for (idx = 0; idx < nLayers; ++idx, ++theLayer) {
  116.  
  117.             if (theLayer->outlineStyle != nil)
  118.                 GXDisposeStyle(theLayer->outlineStyle);
  119.             
  120.             if (theLayer->outlineTransform != nil)
  121.                 GXDisposeTransform(theLayer->outlineTransform);
  122.                         
  123.         }//end for
  124.         
  125.         status = PSReleaseWorkSpace(hIEGlobals);
  126.         ncheck(status);
  127.         
  128. failed_faceSpace:        
  129.         return(status);
  130.         
  131.     }//FixUpTextFace
  132.  
  133. /******************************************
  134.  
  135.     Function:        FixUpTextFaces
  136.     
  137.     Routine goes through the text faces of a shape
  138.     and makes sure that all text faces will render
  139.     properly into bitmaps.
  140.     
  141. ********************************************/
  142. OSErr            FixUpTextFaces(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxMapping *finalMapping);
  143. OSErr            FixUpTextFaces(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxMapping *finalMapping)
  144.     {
  145.         OSErr                        status;
  146.         gxShapeType            theType;
  147.         gxStyle                    aStyle, *pStyle;
  148.         long                        runCount, idx;
  149.         Handle                    workHandle;
  150.  
  151.         theType = GXGetShapeType(theShape);
  152.         if (theType == gxLayoutType) {
  153.     
  154.             GXPrimitiveShape(theShape);
  155.             theType = GXGetShapeType(theShape);
  156.             if (theType == gxEmptyType)
  157.                 return(noErr);
  158.                 
  159.         }//end if
  160.  
  161.         /**** Look at all of the styles and fix the text faces ****/
  162.         
  163.         aStyle = GXGetShapeStyle(theShape);
  164.  
  165.         /** Process the shape's root style **/        
  166.  
  167.         status = FixUpTextFace(hIEGlobals, aStyle, finalMapping);
  168.         nrequire(status, failed_fixFace);
  169.  
  170.         /** Process any styles in the geometry **/
  171.         
  172.         if (theType == gxGlyphType)     {
  173.  
  174.             /** Allocate memory for the styles **/        
  175.             
  176.             GXGetGlyphs(theShape, nil, nil, nil, nil, nil, &runCount, nil, nil);
  177.             status = PSSetWorkSpaceSize(hIEGlobals, runCount * sizeof(gxStyle));
  178.             nrequire(status, failed_workSpace);
  179.             workHandle = (*hIEGlobals)->hWorkSpace;
  180.             HLock(workHandle);
  181.             pStyle = (gxStyle*)*workHandle;
  182.             
  183.             GXGetGlyphs(theShape, nil, nil, nil, nil, nil, &runCount, nil, pStyle);
  184.             
  185.             for (idx = 0; idx < runCount; ++idx) {
  186.  
  187.                 status = FixUpTextFace(hIEGlobals, *pStyle++, finalMapping);
  188.                 nrequire(status, failed_fixFace1);
  189.                 
  190.             }//end for
  191.         
  192. failed_fixFace1:        
  193.             {
  194.                 OSErr saveStatus = PSReleaseWorkSpace(hIEGlobals);
  195.                 if (status == noErr)
  196.                     status = saveStatus;
  197.             }
  198.             
  199.         }//end if
  200.  
  201. failed_workSpace:
  202. failed_fixFace:
  203.  
  204.         return(status);
  205.     
  206.     }//FixUpTextFaces
  207.  
  208. #endif
  209.  
  210.  
  211. /*****************************************
  212.  
  213.     Function:        PSRasterizeShape
  214.     
  215.     Routine rasterizes a shape at device resolution
  216.     for imaging by PostScript.  We don't care about clips
  217.     because the transform hiearchy has already been set up 
  218.     by the imaging engine before this routine even gets called,
  219.     we just need to rasterize the right number of bits.
  220.     
  221.     hIEGlobals:                Imaging Engine globals handle
  222.     theShape:                    the shape to rasterize.
  223.     parents:                    pointer to list of parent transforms.  (nil means ignore, implies leave shape in device space)
  224.     depth:                        number of parents.                                         (pass zero if nil passed for above)
  225.     
  226. *******************************************/
  227.  
  228. OSErr    PSRasterizeShape(TIEGlobalsHdl hIEGlobals, gxShape theShape, gxTransform *parents, long depth)
  229.     {
  230.         OSErr                        status;
  231.         gxMapping                aMapping;
  232.         gxTag                        aTag;
  233.         gxMapping                *deviceMapping;
  234.         gxMapping                additionalMapping;                        // This mapping will be used by PS to concatenate with CTM for bitmap.
  235.         gxMapping                mapShapeThrough;                            // concatenation of all mappings for shape.
  236.         gxTransform            oldTransform;                                    // shape's old transform.
  237.         gxTransform            newTransform;
  238.         gxTransform            *pTransform;
  239.         long                        i;
  240.                 
  241.         check( (parents != nil) || (depth == 0) );
  242.         
  243.         /* save the shape's transform before we muck around with it. */
  244.         
  245.         oldTransform = GXCloneTransform(GXGetShapeTransform(theShape));
  246.  
  247.         
  248.         /* first map the shape through its own mapping */
  249.         
  250.         if (parents == nil) {
  251.         
  252.             ResetMapping(&mapShapeThrough);
  253.  
  254.         } else {
  255.         
  256.             GXGetShapeMapping(theShape, &mapShapeThrough);
  257.             
  258.             
  259.             /** Now map it through the parents **/
  260.             
  261.             pTransform = &(parents[depth - 1]);                // Point to shape's direct parents.
  262.             
  263.             for (i = 0; i < depth; ++i) {
  264.     
  265.                 GXGetTransformMapping(*pTransform, &aMapping);
  266.                 MapMapping(&mapShapeThrough, &aMapping);
  267.                 
  268.                 --pTransform;
  269.     
  270.             }//end for
  271.             
  272.     
  273.             /* Now apply the device mapping, but only if a transform list was passed in */
  274.                     
  275.             deviceMapping = &( (*hIEGlobals)->deviceMapping );        
  276.             MapMapping(&mapShapeThrough, deviceMapping);
  277.             
  278.             /** Tag the shape with the rasterizedShapeTag, the tag contains the inverse of the mapping. **/
  279.     
  280.             InvertMapping(&additionalMapping, &mapShapeThrough);
  281.             aTag = GXNewTag(rasterizedShapeTag, sizeof(gxMapping), &additionalMapping);
  282.             GXSetShapeTags(theShape, rasterizedShapeTag, 0, 0, 1, &aTag);
  283.             GXDisposeTag(aTag);
  284.     
  285.         }//end if
  286.         
  287.         #ifndef SKIADOESNTDROPOUT
  288.         status = FixUpTextFaces(hIEGlobals, theShape, &mapShapeThrough);
  289.         nrequire(status, failed_fixUpFaces);
  290.         #endif
  291.         
  292.                                                     
  293.         /**** Now rasterize the shape ****/
  294.         
  295.         newTransform = GXNewTransform();                                                        // Make a new trasnform with no clip
  296.         GXSetTransformMapping(newTransform, &mapShapeThrough);            // Give it the concatenation.
  297.         GXSetShapeTransform(theShape, newTransform);                                // Give the shape this transform.
  298.         GXDisposeTransform(newTransform);                                                        // Don't need our reference any more.
  299.         GXSetShapeType(theShape, gxBitmapType);                                            // Convert the shape to a bitmap.
  300.         
  301.         status = GXGetGraphicsError(nil);
  302.         nrequire(status, failed_Rasterize);
  303.                 
  304.         status = GXGetGraphicsError(nil);
  305.         ncheck(status);
  306.  
  307. failed_fixUpFaces:
  308. failed_Rasterize:
  309.  
  310.         /** Restore the shape's transform **/
  311.  
  312.         GXSetShapeTransform(theShape, oldTransform);
  313.         GXDisposeTransform(oldTransform);
  314.         
  315.         return(status);
  316.         
  317.     }//PSRasterizeShape
  318.